void disp_vec_options(const char* vecname, arglist_t* ap);
void disp_vecs();
void disp_vec(const char* vecname);
+int validate_formats();
void init_vecs();
void exit_vecs();
void disp_formats(int version);
static bool isSizeSwapped;
static char* showlist = nullptr; // if true show a list instead of download tracks
-static char* track = nullptr; // if not 0 only download this track, if 0 download all
+static char* track = nullptr; // if not 0 only download this track, if 0 download all
-static char* opt_dump_file = nullptr; // dump raw data to this file (optional)
+static char* opt_dump_file = nullptr; // dump raw data to this file (optional)
static char* opt_input_dump_file = nullptr; // if true input is from a dump-file instead of serial console
static gbfile* dumpfile = nullptr; // used for creating bin/RAW datadump files, useful for testing
static gbfile* in_file = nullptr; // used for reading from bin/RAW datadump files, useful for testing
globalsat_probe_device();
}
-static void
-wr_init(const QString& fname)
-{
- if (global_opts.debug_level > 1) {
- printf(MYNAME " wr_init()\n");
- }
- serial_init(qPrintable(fname));
-}
-
-
static void
rd_deinit()
{
}
}
-static void
-wr_deinit()
-{
- if (global_opts.debug_level > 1) {
- printf(MYNAME " wr_deinit()\n");
- }
- serial_deinit();
-}
-
static void track_read();
-
static void
waypoint_read()
{
// This used the serial communication to the watch
ff_vecs_t globalsat_sport_vecs = {
- ff_type_serial, //type
- FF_CAP_RW_ALL, //cap[3]
- rd_init, //rd_init
- wr_init, //wr_init
- rd_deinit, //rd_deinit
- wr_deinit, //wr_deinit
- data_read, //read
- nullptr, //write
- nullptr, //exit
- globalsat_args, //args
- CET_CHARSET_ASCII, 0 //encode,fixed_encode
- //NULL //name dynamic/internal?
- , NULL_POS_OPS,
- nullptr
-};
-
-// This reads from a RAW dump bile from a watch
-// Useful for testing generated dumpfile with
-// gpsbabel -i globalsat,dump-file=<dumpfilename> -f /dev/ttyUSB0 -o gpx,garminextensions -F <1:st gpx file name>
-// gpsbabel -i globalsat-bin -f <dumpfilename> -o gpx,garminextensions -F <2:nd gpx file name>
-ff_vecs_t globalsat_sport_fvecs = {
- ff_type_serial, //type
- FF_CAP_RW_ALL, //cap[3]
- rd_init, //rd_init
- wr_init, //wr_init
- rd_deinit, //rd_deinit
- wr_deinit, //wr_deinit
- data_read, //read
- nullptr, //write
- nullptr, //exit
- globalsat_args, //args
- CET_CHARSET_ASCII, 0 //encode,fixed_encode
- //NULL //name dynamic/internal?
- , NULL_POS_OPS,
+ ff_type_serial, // type
+ { // cap
+ ff_cap_none, // waypoints
+ ff_cap_read, // tracks
+ ff_cap_none, // routes
+ },
+ rd_init, // rd_init
+ nullptr, // wr_init
+ rd_deinit, // rd_deinit
+ nullptr, // wr_deinit
+ data_read, // read
+ nullptr, // write
+ nullptr, // exit
+ globalsat_args, // args
+ CET_CHARSET_ASCII, // encode
+ 0, // fixed_encode
+ NULL_POS_OPS, // position_ops
nullptr
};
./gpsbabel -i itracku -f com14 -o gpx -F out.gpx
*/
+#include <cmath> // for lround, round, floor
+#include <cstdarg> // for va_end, va_list, va_start
+#include <cstdio> // for fprintf, stderr, SEEK_END, fflush, sscanf, vfprintf
+#include <cstdint>
+#include <cstring> // for memcpy, strcmp, strlen, strncmp
+#include <ctime> // for gmtime
+
+#include <QtCore/QByteArray> // for QByteArray
+#include <QtCore/QDate> // for QDate
+#include <QtCore/QDateTime> // for QDateTime
+#include <QtCore/QString> // for QString
+#include <QtCore/QTime> // for QTime
+#include <QtCore/Qt> // for UTC
+#include <QtCore/QtGlobal> // for qPrintable
+
#include "defs.h"
-#include "gbser.h"
-#include <cctype>
-#include <cmath>
-#include <cstdio>
+#include "gbser.h" // for gbser_read_line, gbser_write, gbser_deinit, gbser_flush, gbser_init, gbser_is_serial, gbser_read_wait, gbser_ERROR, gbser_OK
+#include "gbfile.h" // for gbfile, gbfclose, gbfopen, gbfseek, gbfread, gbfwrite, gbftell, gbsize_t
+#include "src/core/datetime.h" // for DateTime
+
#define MYNAME "itracku"
return
(uint32_t)d * 1000000 + // multiply integer degrees to shift it to the right digits.
- (uint32_t)(f * 600000.0) + // multiply fractional part to convert to minutes and to to shift it to the right digits.
+ (uint32_t)round((f * 600000.0)) + // multiply fractional part to convert to minutes and to to shift it to the right digits.
((sign > 0) ? 0 : 0x80000000); // add 0x80000000 for negative degrees
}
le_write32(d->longitude, deg_to_deg_min(wp->longitude));
le_write32(d->latitude, deg_to_deg_min(wp->latitude));
le_write32(d->creation_time, encode_itracku_time(wp->creation_time.toTime_t()));
- d->speed = MPS_TO_KNOTS(wp->speed);
+ d->speed = round(MPS_TO_KNOTS(wp->speed));
le_write16(d->altitude, wp->altitude);
d->flag = 0xff;
}
/**************************************************************************/
-// capabilities below means: we can only read and write waypoints
-// please change this depending on your new module
ff_vecs_t itracku_vecs = {
- ff_type_file,
+ ff_type_serial,
{
ff_cap_read /* waypoints */,
ff_cap_read /* tracks */,
itracku_rd_deinit,
nullptr,
itracku_read,
- itracku_write,
+ nullptr,
itracku_exit,
itracku_args,
CET_CHARSET_ASCII, 0, /* ascii is the expected character set */
warning(MYNAME ": QTextCodec::codecForLocale() is %s, mib %d\n",
defaultcodec->name().constData(),defaultcodec->mibEnum());
}
-
break;
+
+ /*
+ * Undocumented '-@' option for test.
+ */
+ case '@':
+ return validate_formats();
+
/*
* Undocumented '-vs' option for GUI wrappers.
*/
{
}
-static void
-nav_wr_init(const QString&)
-{
- fatal(MYNAME ": Does not support writing Navicache files.\n");
-}
-
-static void
-nav_wr_deinit()
-{
-}
-
-static void
-nav_write()
-{
-}
-
ff_vecs_t navicache_vecs = {
ff_type_file,
{ ff_cap_read, ff_cap_none, ff_cap_none },
nav_rd_init,
- nav_wr_init,
+ nullptr,
nav_rd_deinit,
- nav_wr_deinit,
+ nullptr,
nav_read,
- nav_write,
+ nullptr,
nullptr,
nav_args,
CET_CHARSET_UTF8, 0 /* CET-REVIEW */
xml_deinit();
}
-static void
-wr_init(const QString&)
-{
- fatal("Writing file of type %s is not supported\n", MYNAME);
-}
-
void wpt_s(xg_string, const QXmlStreamAttributes*)
{
if (isFirst == 1) {
ff_cap_read /* routes */
},
rd_init,
- wr_init,
+ nullptr,
rd_deinit,
nullptr,
data_read,
}
-static void
-wr_init(const QString&)
-{
- fatal(MYNAME ":Not enough information is known about this format to write it.\n");
-}
-
ff_vecs_t saroute_vecs = {
ff_type_file,
{ ff_cap_none, ff_cap_read, ff_cap_none},
rd_init,
- wr_init,
+ nullptr,
rd_deinit,
nullptr,
my_read,
--- /dev/null
+gpsbabel -@
+
#define MYNAME "TPO"
static char* dumpheader = nullptr;
+#ifdef ENABLE_TPO_WRITE
static char* output_state = nullptr;
+#endif
-/*
+#ifdef ENABLE_TPO_WRITE
static
arglist_t tpo2_args[] = {
{ "dumpheader", &dumpheader, "Display the file header bytes",
"CA", ARGTYPE_STRING, ARG_NOMINMAX} ,
ARG_TERMINATOR
};
-*/
+#else
//
// Note that we've disabled the write capabilities for the tpo2
// format at present. The "testo" tests were failing on some
arglist_t tpo2_args[] = {
ARG_TERMINATOR
};
+#endif
static
arglist_t tpo3_args[] = {
static gbfile* tpo_file_in;
+static double track_length;
+
+#ifdef ENABLE_TPO_WRITE
static gbfile* tpo_file_out;
-//static short_handle mkshort_handle;
static double output_track_lon_scale;
static double output_track_lat_scale;
static unsigned int track_out_count;
static double first_track_waypoint_lat;
static double first_track_waypoint_lon;
-static double track_length;
static double last_waypoint_x;
static double last_waypoint_y;
static double last_waypoint_z;
+#endif
/*******************************************************************************/
/* READ */
-
+#ifdef ENABLE_TPO_WRITE
/*******************************************************************************/
/* WRITE */
/*******************************************************************************/
static void
tpo_write_file_header()
{
- // this assertion will quiet gcc 7.3 warnings about output_state in the strncmp calls
- // warning: argument 2 null where non-null expected [-Wnonnull]
assert(output_state != nullptr);
/* force upper-case state name */
track_out_count = 0;
track_disp_all(tpo_track_hdr, tpo_track_tlr, tpo_track_disp);
}
+#endif // ENABLE_TPO_WRITE
/* TPO 2.x format can read tracks only */
ff_vecs_t tpo2_vecs = {
ff_type_file, /* ff_type_internal */
- /* { ff_cap_none | ff_cap_none, ff_cap_read | ff_cap_write, ff_cap_none | ff_cap_none }, */
+#ifdef ENABLE_TPO_WRITE
+ { ff_cap_none, (ff_cap)(ff_cap_read | ff_cap_write), ff_cap_none },
+#else
{ ff_cap_none, ff_cap_read, ff_cap_none },
+#endif
tpo_rd_init,
+#ifdef ENABLE_TPO_WRITE
tpo_wr_init,
+#else
+ nullptr,
+#endif
tpo_rd_deinit,
+#ifdef ENABLE_TPO_WRITE
tpo_wr_deinit,
+#else
+ nullptr,
+#endif
tpo_read,
+#ifdef ENABLE_TPO_WRITE
tpo_write,
+#else
+ nullptr,
+#endif
nullptr,
tpo2_args,
CET_CHARSET_ASCII, 0 /* CET-REVIEW */
ff_type_file, /* ff_type_internal */
{ ff_cap_read, ff_cap_read, ff_cap_read },
tpo_rd_init,
- tpo_wr_init,
+ nullptr,
tpo_rd_deinit,
- tpo_wr_deinit,
+ nullptr,
tpo_read,
- tpo_write,
+ nullptr,
nullptr,
tpo3_args,
CET_CHARSET_ASCII, 0 /* CET-REVIEW */
;
}
}
+
+static bool
+validate_vec(const vecs_t* vec)
+{
+ bool ok = true;
+
+ if (!((vec->vec->cap[0]|vec->vec->cap[1]|vec->vec->cap[2]) & ff_cap_write)) {
+ if (vec->vec->wr_init != nullptr) {
+ printf("ERROR no write capability but non-null wr_init %s\n", vec->name);
+ ok = false;
+ }
+ }
+ if (!((vec->vec->cap[0]|vec->vec->cap[1]|vec->vec->cap[2]) & ff_cap_read)) {
+ if (vec->vec->rd_init != nullptr) {
+ printf("ERROR no read capbility but non-null rd_init %s\n", vec->name);
+ ok = false;
+ }
+ }
+ if ((vec->vec->cap[0]|vec->vec->cap[1]|vec->vec->cap[2]) & ff_cap_write) {
+ if (vec->vec->wr_init == nullptr) {
+ printf("ERROR write capability but null wr_init %s\n", vec->name);
+ ok = false;
+ }
+ }
+ if ((vec->vec->cap[0]|vec->vec->cap[1]|vec->vec->cap[2]) & ff_cap_read) {
+ if (vec->vec->rd_init == nullptr) {
+ printf("ERROR read capability but null rd_init %s\n", vec->name);
+ ok = false;
+ }
+ }
+
+ if (vec->vec->wr_init != nullptr) {
+ if (vec->vec->write == nullptr) {
+ printf("ERROR nonnull wr_init but null write %s\n", vec->name);
+ ok = false;
+ }
+ if (vec->vec->wr_deinit == nullptr) {
+ printf("ERROR nonnull wr_init but null wr_deinit %s\n", vec->name);
+ ok = false;
+ }
+ }
+ if (vec->vec->wr_init == nullptr) {
+ if (vec->vec->write != nullptr) {
+ printf("ERROR null wr_init with non-null write %s\n", vec->name);
+ ok = false;
+ }
+ if (vec->vec->wr_deinit != nullptr) {
+ printf("ERROR null wr_init with non-null wr_deinit %s\n", vec->name);
+ ok = false;
+ }
+ }
+
+ if (vec->vec->rd_init != nullptr) {
+ if (vec->vec->read == nullptr) {
+ printf("ERROR nonnull rd_init but null read %s\n", vec->name);
+ ok = false;
+ }
+ if (vec->vec->rd_deinit == nullptr) {
+ printf("ERROR nonnull rd_init but null rd_deinit %s\n", vec->name);
+ ok = false;
+ }
+ }
+ if (vec->vec->rd_init == nullptr) {
+ if (vec->vec->read != nullptr) {
+ printf("ERROR null rd_init with non-null read %s\n", vec->name);
+ ok = false;
+ }
+ if (vec->vec->rd_deinit != nullptr) {
+ printf("ERROR null rd_init with non-null rd_deinit %s\n", vec->name);
+ ok = false;
+ }
+ }
+
+ return ok;
+}
+
+int validate_formats()
+{
+ bool ok = true;
+
+ const vecs_t* vec = vec_list;
+ while (vec->vec) {
+ ok = validate_vec(vec) && ok;
+ vec++;
+ }
+
+ return ok? 0 : 1;
+}
}
}
-static void
-vpl_wr_init(const QString&)
-{
- fatal("Writing file of type %s is not support\n", MYNAME);
-}
-
/*******************************************************************************
* Local Functions
*******************************************************************************/
ff_cap_none /* routes */
},
vpl_rd_init,
- vpl_wr_init,
+ nullptr,
vpl_rd_deinit,
nullptr,
vpl_read,
xml_deinit();
}
-static void
-yahoo_wr_init(const QString&)
-{
- fatal("Writing file of type %s is not supported\n", MYNAME);
-}
-
void wpt_s(xg_string, const QXmlStreamAttributes*)
{
wpt_tmp = new Waypoint;
ff_vecs_t yahoo_vecs = {
ff_type_file,
- { ff_cap_read },
+ { ff_cap_read, ff_cap_none, ff_cap_none },
yahoo_rd_init,
- yahoo_wr_init,
+ nullptr,
yahoo_rd_deinit,
nullptr,
yahoo_read,